Skip to content

[Windows] Fix Preserve ScrollView offsets when Orientation changes to Neither#34827

Merged
kubaflo merged 2 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-34671
Apr 17, 2026
Merged

[Windows] Fix Preserve ScrollView offsets when Orientation changes to Neither#34827
kubaflo merged 2 commits into
dotnet:inflight/currentfrom
SubhikshaSf4851:Fix-34671

Conversation

@SubhikshaSf4851
Copy link
Copy Markdown
Contributor

Note

Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment whether this change resolves your issue. Thank you!

Root Cause

On Windows, when ScrollOrientation was set to Neither, the ScrollViewer used Disabled scroll modes and scroll bars. Disabling scrolling caused the control to internally reset its scroll offsets to the origin (0,0), instead of preserving the current position.

Description of Change

Bug fix for ScrollView offset preservation:

  • Updated ScrollViewerExtensions.cs so that when ScrollOrientation.Neither is set, the scroll bars are set to Hidden (instead of Disabled) and the scroll modes are set to Disabled. This preserves the current scroll position instead of resetting it to (0,0). When leaving Neither, scroll modes are restored to Auto.

Testing :

  • Added a new manual test page Issue34671.cs that demonstrates and allows manual verification of the bug and its fix. The page provides controls to change orientation, scroll to a specific offset, and reset the state, as well as labels to display current scroll position and actions.
  • Added a new automated UI test Issue34671.cs (for Windows and Android) that verifies the scroll position remains non-zero after changing orientation to Neither, ensuring the fix is validated in CI.

Note :

The Test for this fix is already covered in PR #34672, which has been merged into the inflight branch. The same test has been included here temporarily so the Gate phase passes. Once PR #34672 is merged into main, the duplicate test in this PR can be reverted, and the Windows-specific test from PR #34672 can be enabled.

Issues Fixed

Fixes #34671

Tested the behavior in the following platforms

  • Windows
  • Android
  • iOS
  • Mac
Before Issue Fix After Issue Fix
BeforeFix34671.mp4
AfterFix34671.1.mp4

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 6, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34827

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34827"

@dotnet-policy-service dotnet-policy-service Bot added the community ✨ Community Contribution label Apr 6, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Hey there @@SubhikshaSf4851! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@dotnet-policy-service dotnet-policy-service Bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Apr 6, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review April 14, 2026 08:25
Copilot AI review requested due to automatic review settings April 14, 2026 08:25
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run maui-pr-uitests , maui-pr-devicetests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a Windows-specific ScrollView regression where switching ScrollOrientation to Neither resets the underlying WinUI ScrollViewer offsets back to (0,0). The fix updates the Windows ScrollViewer configuration to preserve offsets while still preventing user scrolling, and adds a HostApp repro page plus an Appium UI test.

Changes:

  • Windows: update ScrollViewerExtensions.UpdateScrollBarVisibility to use hidden scrollbars (not disabled) and disable scroll modes when orientation is Neither.
  • Tests: add Issue34671 HostApp repro page and an Appium UI test validating offsets remain non-zero after switching to Neither.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/Core/src/Platform/Windows/ScrollViewerExtensions.cs Adjusts WinUI ScrollViewer scrollbar visibility/scroll modes for ScrollOrientation.Neither to preserve offsets.
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34671.cs Adds an Appium UI test intended to verify scroll offsets are preserved when switching orientation to Neither.
src/Controls/tests/TestCases.HostApp/Issues/Issue34671.cs Adds a manual repro page with buttons/labels to demonstrate and validate the orientation/offset behavior.

{
new Label
{
Text = "Repro for dotnet/maui#34671: scroll away from the origin, then set Orientation to Neither. On iOS, ScrollX and ScrollY reset to 0 instead of being preserved.",
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repro description text says "On iOS, ScrollX and ScrollY reset to 0" but this issue/PR is Windows-specific (#34671). This is misleading for manual validation (and for anyone using the page as a repro reference). Update the text to reference Windows (and/or all platforms if intended).

Suggested change
Text = "Repro for dotnet/maui#34671: scroll away from the origin, then set Orientation to Neither. On iOS, ScrollX and ScrollY reset to 0 instead of being preserved.",
Text = "Repro for dotnet/maui#34671: scroll away from the origin, then set Orientation to Neither. On Windows, ScrollX and ScrollY reset to 0 instead of being preserved.",

Copilot uses AI. Check for mistakes.
Comment on lines +20 to +27
App.Tap("ScrollToReproOffsetButton");
App.WaitForTextToBePresentInElement("LastActionLabel", "Scrolled to approx");
App.WaitForElement("SetNeitherButton");
App.Tap("SetNeitherButton");

var offsetText = App.WaitForElement("OffsetLabel").GetText()
?? throw new InvalidOperationException("OffsetLabel text was null.");
var offsetParts = offsetText.Split('|', StringSplitOptions.TrimEntries);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test reads OffsetLabel immediately after tapping "SetNeitherButton" without waiting for the UI to update for the Neither action (the page updates labels asynchronously after a delay). This can make the test flaky and can also produce a false positive by asserting on the pre-change offsets. Add an explicit wait that confirms the Neither action has completed (e.g., wait for LastActionLabel/OrientationLabel to reflect Neither) before parsing OffsetLabel.

Copilot uses AI. Check for mistakes.
@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 17, 2026

🚦 Gate — Test Before and After Fix

👋 @SubhikshaSf4851 — new gate results are available. Please review the latest session below.

🚦 Gate Session2ef7c46 · Test sample Added · 2026-04-17 09:57 UTC

Gate Result: ✅ PASSED

Platform: WINDOWS · Base: main · Merge base: eb0b82fe

Test Without Fix (expect FAIL) With Fix (expect PASS)
🖥️ Issue34671 Issue34671 ✅ FAIL — 552s ✅ PASS — 443s
🔴 Without fix — 🖥️ Issue34671: FAIL ✅ · 552s
  Determining projects to restore...
  Restored D:\a\1\s\src\Controls\src\Core\Controls.Core.csproj (in 44 sec).
  Restored D:\a\1\s\src\Controls\Maps\src\Controls.Maps.csproj (in 43.92 sec).
  Restored D:\a\1\s\src\Controls\Foldable\src\Controls.Foldable.csproj (in 369 ms).
  Restored D:\a\1\s\src\BlazorWebView\src\Maui\Microsoft.AspNetCore.Components.WebView.Maui.csproj (in 3.67 sec).
  Restored D:\a\1\s\src\Graphics\src\Graphics.Win2D\Graphics.Win2D.csproj (in 23 ms).
  Restored D:\a\1\s\src\Essentials\src\Essentials.csproj (in 14 ms).
  Restored D:\a\1\s\src\Core\src\Core.csproj (in 87 ms).
  Restored D:\a\1\s\src\Core\maps\src\Maps.csproj (in 20 ms).
  Restored D:\a\1\s\src\Graphics\src\Graphics\Graphics.csproj (in 3.59 sec).
  Restored D:\a\1\s\src\Controls\src\Xaml\Controls.Xaml.csproj (in 24 ms).
  Restored D:\a\1\s\src\Controls\tests\TestCases.HostApp\Controls.TestCases.HostApp.csproj (in 615 ms).
  3 of 14 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
  Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
  Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:05:47.86
  Determining projects to restore...
  Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils\VisualTestUtils.csproj (in 751 ms).
  Restored D:\a\1\s\src\TestUtils\src\UITest.NUnit\UITest.NUnit.csproj (in 1.34 sec).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Core\UITest.Core.csproj (in 4 ms).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Appium\UITest.Appium.csproj (in 2.1 sec).
  Restored D:\a\1\s\src\TestUtils\src\VisualTestUtils.MagickNet\VisualTestUtils.MagickNet.csproj (in 5.04 sec).
  Restored D:\a\1\s\src\TestUtils\src\UITest.Analyzers\UITest.Analyzers.csproj (in 9.39 sec).
  Restored D:\a\1\s\src\Controls\tests\CustomAttributes\Controls.CustomAttributes.csproj (in 5 ms).
  Restored D:\a\1\s\src\Controls\tests\TestCases.WinUI.Tests\Controls.TestCases.WinUI.Tests.csproj (in 8.6 sec).
  7 of 15 projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
  Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
  UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
  UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
  UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
  VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
  VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
  UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
  Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/17/2026 9:49:26 AM FixtureSetup for Issue34671(Windows)
>>>>> 4/17/2026 9:49:36 AM Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither Start
>>>>> 4/17/2026 9:49:39 AM Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither Stop
>>>>> 4/17/2026 9:49:39 AM Log types: 
  Failed Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither [4 s]
  Error Message:
     ScrollX should remain non-zero after setting orientation to Neither.
Assert.That(scrollX, Is.GreaterThan(0d))
  Expected: greater than 0.0d
  But was:  0.0d

  Stack Trace:
     at Microsoft.Maui.TestCases.Tests.Issues.Issue34671.Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:line 37

1)    at Microsoft.Maui.TestCases.Tests.Issues.Issue34671.Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither() in /_/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:line 37


NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.11]   Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.30]   Discovered:  Controls.TestCases.WinUI.Tests

Total tests: 1
     Failed: 1
Test Run Failed.
 Total time: 33.1345 Seconds

🟢 With fix — 🖥️ Issue34671: PASS ✅ · 443s
  Determining projects to restore...
  All projects are up-to-date for restore.
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics.Win2D -> D:\a\1\s\artifacts\bin\Graphics.Win2D\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Graphics.Win2D.WinUI.Desktop.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Maps -> D:\a\1\s\artifacts\bin\Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Maps.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.Maps -> D:\a\1\s\artifacts\bin\Controls.Maps\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Maps.dll
  Microsoft.AspNetCore.Components.WebView.Maui -> D:\a\1\s\artifacts\bin\Microsoft.AspNetCore.Components.WebView.Maui\Debug\net10.0-windows10.0.19041.0\Microsoft.AspNetCore.Components.WebView.Maui.dll
  Controls.Xaml -> D:\a\1\s\artifacts\bin\Controls.Xaml\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Xaml.dll
  Controls.Foldable -> D:\a\1\s\artifacts\bin\Controls.Foldable\Debug\net10.0-windows10.0.19041.0\Microsoft.Maui.Controls.Foldable.dll
  Controls.TestCases.HostApp -> D:\a\1\s\artifacts\bin\Controls.TestCases.HostApp\Debug\net10.0-windows10.0.19041.0\win-x64\Controls.TestCases.HostApp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:05:30.34
  Determining projects to restore...
  All projects are up-to-date for restore.
  Controls.CustomAttributes -> D:\a\1\s\artifacts\bin\Controls.CustomAttributes\Debug\net10.0\Controls.CustomAttributes.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Graphics -> D:\a\1\s\artifacts\bin\Graphics\Debug\net10.0\Microsoft.Maui.Graphics.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Essentials -> D:\a\1\s\artifacts\bin\Essentials\Debug\net10.0\Microsoft.Maui.Essentials.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Core -> D:\a\1\s\artifacts\bin\Core\Debug\net10.0\Microsoft.Maui.dll
  Controls.Core.Design -> D:\a\1\s\artifacts\bin\Controls.Core.Design\Debug\net472\Microsoft.Maui.Controls.DesignTools.dll
  Controls.BindingSourceGen -> D:\a\1\s\artifacts\bin\Controls.BindingSourceGen\Debug\netstandard2.0\Microsoft.Maui.Controls.BindingSourceGen.dll
  ##vso[build.updatebuildnumber]10.0.70-ci+azdo.13867296
  Controls.Core -> D:\a\1\s\artifacts\bin\Controls.Core\Debug\net10.0\Microsoft.Maui.Controls.dll
  UITest.Core -> D:\a\1\s\artifacts\bin\UITest.Core\Debug\net10.0\UITest.Core.dll
  VisualTestUtils -> D:\a\1\s\artifacts\bin\VisualTestUtils\Debug\netstandard2.0\VisualTestUtils.dll
  UITest.NUnit -> D:\a\1\s\artifacts\bin\UITest.NUnit\Debug\net10.0\UITest.NUnit.dll
  VisualTestUtils.MagickNet -> D:\a\1\s\artifacts\bin\VisualTestUtils.MagickNet\Debug\netstandard2.0\VisualTestUtils.MagickNet.dll
  UITest.Appium -> D:\a\1\s\artifacts\bin\UITest.Appium\Debug\net10.0\UITest.Appium.dll
  UITest.Analyzers -> D:\a\1\s\artifacts\bin\UITest.Analyzers\Debug\netstandard2.0\UITest.Analyzers.dll
  Controls.TestCases.WinUI.Tests -> D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
Test run for D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll (.NETCoreApp,Version=v10.0)
VSTest version 18.0.1 (x64)

Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
NUnit Adapter 4.5.0.0: Test execution started
Running selected tests in D:\a\1\s\artifacts\bin\Controls.TestCases.WinUI.Tests\Debug\net10.0\Controls.TestCases.WinUI.Tests.dll
   NUnit3TestExecutor discovered 1 of 1 NUnit test cases using Current Discovery mode, Non-Explicit run
>>>>> 4/17/2026 9:56:51 AM FixtureSetup for Issue34671(Windows)
>>>>> 4/17/2026 9:57:00 AM Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither Start
>>>>> 4/17/2026 9:57:04 AM Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither Stop
  Passed Issue34671ScrollPositionIsPreservedWhenOrientationChangesToNeither [3 s]
NUnit Adapter 4.5.0.0: Test execution complete
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.8.2+699d445a1a (64-bit .NET 10.0.0)
[xUnit.net 00:00:00.11]   Discovering: Controls.TestCases.WinUI.Tests
[xUnit.net 00:00:00.39]   Discovered:  Controls.TestCases.WinUI.Tests

Test Run Successful.
Total tests: 1
     Passed: 1
 Total time: 26.7323 Seconds

📁 Fix files reverted (1 files)
  • src/Core/src/Platform/Windows/ScrollViewerExtensions.cs

@MauiBot
Copy link
Copy Markdown
Collaborator

MauiBot commented Apr 17, 2026

🤖 AI Summary

👋 @SubhikshaSf4851 — new AI review results are available. Please review the latest session below.

📊 Review Session2ef7c46 · Test sample Added · 2026-04-17 10:57 UTC
🔍 Pre-Flight — Context & Validation

Issue: #34671 - [Windows] ScrollView offsets do not preserve when Orientation changes to Neither
PR: #34827 - [Windows] Fix Preserve ScrollView offsets when Orientation changes to Neither
Platforms Affected: Windows (primary); Android included in test via #if WINDOWS || ANDROID temporarily
Files Changed: 1 implementation, 2 test

Key Findings

  • Root cause: ScrollBarVisibility.Disabled on WinUI causes ScrollViewer to reset HorizontalOffset/VerticalOffset to (0,0). Using Hidden instead preserves the scroll position.
  • Fix is Windows-only in ScrollViewerExtensions.cs — minimal, well-targeted change.
  • Test #if WINDOWS || ANDROID is acknowledged as temporary until PR [iOS] Preserve ScrollView offsets when Orientation changes to Neither #34672 (iOS fix) lands in main.
  • Prior Copilot inline review flagged: (1) description text says "On iOS" (wrong platform), and (2) test reads OffsetLabel immediately after tapping SetNeitherButton without waiting for the async label update (100ms delay).
  • The test does not explicitly wait for "Set Orientation to Neither" text in LastActionLabel before parsing OffsetLabel, which could produce false-positive results or be flaky.

Code Review Summary

Verdict: NEEDS_DISCUSSION
Confidence: high
Errors: 0 | Warnings: 2 | Suggestions: 3

Key code review findings:

  • ⚠️ maui-pr aggregate CI check is failing — needs confirmation whether pre-existing infra issue or caused by this PR
  • ⚠️ #if WINDOWS || ANDROID test scope creates tech debt; should narrow back to #if WINDOWS once [iOS] Preserve ScrollView offsets when Orientation changes to Neither #34672 merges to main; should have inline comment tracking this
  • 💡 double.Parse in test should be double.TryParse with a descriptive Assert for better CI diagnostics (TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:34–35)
  • 💡 Redundant App.WaitForElement("SetNeitherButton") after WaitForTextToBePresentInElement adds no synchronization value
  • 💡 Local Issue34671ViewExtensions class with Row/Column/Assign helpers pollutes the namespace; prefer Grid.SetRow/Grid.SetColumn inline

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34827 Change ScrollBarVisibility.DisabledHidden + ScrollMode.Disabled when Neither; restore ScrollMode.Auto when leaving Neither ✅ PASSED (Gate) ScrollViewerExtensions.cs Windows-only platform fix

🔬 Code Review — Deep Analysis

Code Review — PR #34827

Independent Assessment

What this changes: ScrollViewerExtensions.UpdateScrollBarVisibility previously applied ScrollBarVisibility.Disabled to both axes when orientation was set to Neither. This PR changes that to ScrollBarVisibility.Hidden + ScrollMode.Disabled. When leaving Neither, scroll modes are explicitly restored to Auto. Two new test files are added.

Inferred motivation: On WinUI, ScrollBarVisibility.Disabled carries a side-effect: the ScrollViewer resets its HorizontalOffset/VerticalOffset to (0,0). Switching to Hidden avoids that reset. ScrollMode.Disabled is then needed to prevent user interaction, since Hidden alone still allows scrolling.


Reconciliation with PR Narrative

Author claims: Root cause is confirmed — Disabled visibility causes WinUI to internally reset offsets. The fix uses Hidden + ScrollMode.Disabled to preserve position while blocking input. The PR also notes the || ANDROID test scope is temporary because PR #34672 (the iOS fix) has already merged to the inflight branch but not yet to main, and the gate requires a passing test.

Agreement: My independent assessment matches exactly. The author's root-cause analysis is accurate and the approach is correct for WinUI's documented ScrollBarVisibility semantics.


Findings

⚠️ Warning — CI is failing (maui-pr aggregate check)

maui-prfail and Build Analysisfail. The individual build/pack/unit test sub-jobs all pass, and maui-pr-uitests is still pending. The aggregate failure should be resolved before merge — confirm whether this is a pre-existing infrastructure issue or caused by the UI tests completing with a failure.

⚠️ Warning — #if WINDOWS || ANDROID in test file, but fix is Windows-only

TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:1 — The Issue attribute in the HostApp declares PlatformAffected.UWP, and the fix is entirely in ScrollViewerExtensions.cs (Windows). Including || ANDROID creates an implicit claim that Android behavior is being tested/fixed here. The PR description explains this as temporary (to pass the Gate while PR #34672 is pending), which is a reasonable workaround, but it should carry an inline comment and a tracked follow-up task to scope this back to #if WINDOWS once PR #34672 lands.

💡 Suggestion — double.Parse throws FormatException instead of a test-friendly assertion

TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:34–35 — If the label text is ever malformed or truncated by Appium, double.Parse throws a raw FormatException rather than a NUnit assertion failure, making CI logs hard to diagnose. Prefer:

Assert.That(double.TryParse(scrollXText, NumberStyles.Any, CultureInfo.InvariantCulture, out var scrollX), Is.True,
    $"Could not parse ScrollX from: '{scrollXText}'");

💡 Suggestion — Redundant WaitForElement("SetNeitherButton") after label text wait

TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:22–23 — The test already calls WaitForTextToBePresentInElement("LastActionLabel", "Scrolled to approx") which proves the scroll operation completed and the page is ready. The subsequent App.WaitForElement("SetNeitherButton") checks for a button that was visible at app launch and adds no synchronization value. It can be removed.

💡 Suggestion — Local Row/Column/Assign extension methods duplicate existing patterns

TestCases.HostApp/Issues/Issue34671.cs:265–287 — The Issue34671ViewExtensions class defines Row<TView>(), Column<TView>(), and Assign<TView>(). Other test pages in the same project use Grid.SetRow/Grid.SetColumn directly, and the project already has GridExtension.cs. These local fluent helpers are fine for a one-off page, but they pollute the Maui.Controls.Sample.Issues namespace globally and may shadow future shared helpers. Consider using Grid.SetRow/Grid.SetColumn inline, or extracting to the existing GridExtension.cs if the pattern is worth sharing.


Devil's Advocate

On the core fix: The approach (Hidden + ScrollMode.Disabled) is consistent with WinUI's documented semantics. The restore path (ScrollMode.Auto when leaving Neither) is correct because the subsequent ScrollBarVisibility.Disabled applied to inactive axes by the existing code still prevents scrolling in those directions via WinUI's own ScrollMode.Auto → follow-visibility logic.

On potential regression: MapOrientation passes only one ScrollBarVisibility value (the vertical one for Both). This is a pre-existing asymmetry, not introduced here. The new ScrollMode restoration code is symmetric and does not interact with that asymmetry.

On the || ANDROID test: Android's ScrollView already preserves scroll position on orientation changes (the bug is Windows-only), so the Android test passing is a free regression guard, not a false positive. It is documented as temporary. This is acceptable.

On the double.Parse concern: The label format is controlled entirely by the HostApp and is very unlikely to change mid-test. This is low-severity but genuinely makes failure investigation harder.


Verdict: NEEDS_DISCUSSION

Confidence: high

Summary: The production code fix (ScrollViewerExtensions.cs) is correct, minimal, well-commented, and touches no pre-existing regressions. The test code has minor quality issues (TryParse, redundant wait, wrong platform in description text), and the || ANDROID temporary test scope creates acknowledged short-term tech debt. The main blocker for merge is the failing maui-pr CI check — if that's a pre-existing infra issue unrelated to the PR's changes, the only actionable items are the suggestions above, and the fix is sound. The author should confirm CI status and the follow-up plan for narrowing the test to #if WINDOWS.


🔧 Fix — Analysis & Comparison

Fix Candidates

# Source Approach Test Result Files Changed Notes
1 try-fix Handler-level save/restore offsets in ScrollViewHandler.Windows.cs; extension method unchanged PASS 1 file More complex; fix in wrong abstraction layer
2 try-fix ScrollMode.Disabled only (no visibility change) PASS 1 file Simpler but scrollbar chrome stays visible when Neither UX issue
3 try-fix Reactive: capture offsets before Disabled, restore via ViewChanged+ChangeView FAIL 1 file WinUI ignores ChangeView while in Disabled visibility state
4 try-fix Hidden visibility only (no ScrollMode change) PASS 1 file Simpler but user can still scroll when Neither correctness issue
PR PR #34827 Hidden + ScrollMode.Disabled in extension method; restore ScrollMode.Auto on exit PASSED (Gate) ScrollViewerExtensions.cs Complete: preserves offsets, hides chrome, blocks user scrolling

Cross-Pollination

Model Round New Ideas? Details
claude-opus-4.6 2 Yes Opacity=0 on scrollbar template parts via visual-tree lookup more complex, fragile
claude-sonnet-4.6 2 No NO NEW IDEAS endorses PR fix as most complete
gpt-5.3-codex 2 Yes Event interception (PointerWheelChanged, keyboard) overly complex and fragile
gpt-5.4 2 Yes Same event-interception idea clearly inferior

Exhausted: Yes all approaches explored; new ideas from cross-pollination are strictly worse than PR fix

Selected Fix: PR's fix Hidden + ScrollMode.Disabled in extension method

Reason: The PR's fix is the only approach that satisfies all three requirements simultaneously: (1) preserves scroll offsets (Hidden doesn't trigger WinUI offset reset), (2) hides scrollbar chrome (matching expected UX for Neither orientation), and (3) prevents user scrolling (ScrollMode.Disabled). Attempt 2 passes the test but leaves scrollbars visible; Attempt 4 passes the test but allows user scrolling. The PR's compound approach is correct and minimal for this constraint set.


📋 Report — Final Recommendation

⚠️ Final Recommendation: REQUEST CHANGES

Phase Status

Phase Status Notes
Pre-Flight ✅ COMPLETE Issue #34671 / PR #34827 context gathered; prior Copilot inline review imported
Code Review NEEDS_DISCUSSION (high) 0 errors, 2 warnings, 3 suggestions
Gate ✅ PASSED Windows — tests FAIL without fix, PASS with fix
Try-Fix ✅ COMPLETE 4 attempts: 3 passing, 1 failing
Report ✅ COMPLETE

Code Review Impact on Try-Fix

The code review warning about ScrollMode restoration on exit from Neither directly guided exploration of edge cases in try-fix models. Attempt 4 (Hidden only, no ScrollMode) empirically confirmed the correctness concern: the test passed but user scrolling remained unblocked, validating that the PR's compound Hidden + ScrollMode.Disabled approach is required for correct behavior. Attempt 2 (ScrollMode.Disabled only) confirmed the scrollbar chrome UX concern. Together, these attempts validated every component of the PR's fix is necessary.

Summary

The production fix in ScrollViewerExtensions.cs is correct, minimal, and well-targeted — switching from ScrollBarVisibility.Disabled to Hidden + ScrollMode.Disabled is the right compound solution. Four independent fix explorations confirm no simpler correct alternative exists. The blocking concerns are in the test code: the test lacks a synchronization wait after tapping "SetNeitherButton", creating a potential race with the async 100ms Task.Delay in the button handler; the HostApp description text says "On iOS" (wrong platform); and the #if WINDOWS || ANDROID condition needs an inline comment explaining it's temporary.

Root Cause

On WinUI, ScrollBarVisibility.Disabled has a side-effect: the ScrollViewer resets its HorizontalOffset/VerticalOffset to (0,0). This happens internally in WinUI's layout pass when Disabled visibility is applied. Switching to Hidden preserves the content offset. ScrollMode.Disabled is then required to prevent user input from scrolling while orientation is Neither.

Fix Quality

The production fix (ScrollViewerExtensions.cs) is high quality:

  • ✅ Correct root-cause analysis (confirmed by Try-Fix Attempt 3 which proved reactive restoration doesn't work — the fix must be preventive)
  • ✅ Minimal change (6 lines added, 1 line changed)
  • ✅ Well-commented explaining the WHY
  • ✅ Handles both entry to and exit from Neither (ScrollMode restoration)
  • ✅ No blast radius on other orientations

Test code has three issues that should be addressed before merge:

  1. Flakiness risk (⚠️ prior review + code review): TestCases.Shared.Tests/Tests/Issues/Issue34671.cs:27 — the test reads OffsetLabel immediately after tapping SetNeitherButton, but the HostApp's OnSetNeitherClicked updates labels only after await Task.Delay(100). There's no wait for LastActionLabel to confirm the "Set Orientation to Neither" update completed. This is a potential false-positive or flaky failure. Fix: add App.WaitForTextToBePresentInElement("LastActionLabel", "Set Orientation to Neither") before reading OffsetLabel.
  2. Wrong platform text (💡 prior review): TestCases.HostApp/Issues/Issue34671.cs:61 — description says "On iOS" but this is a Windows bug.
  3. Missing inline comment on #if WINDOWS || ANDROID (⚠️ code review): The PR description explains this is temporary, but the code should have an inline comment so future maintainers understand why Android is included and when to narrow it back to #if WINDOWS.

@MauiBot MauiBot added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Apr 17, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current April 17, 2026 15:40
@kubaflo kubaflo merged commit 38b7ec1 into dotnet:inflight/current Apr 17, 2026
49 of 57 checks passed
@github-actions github-actions Bot added this to the .NET 10 SR7 milestone Apr 17, 2026
PureWeen pushed a commit that referenced this pull request Apr 22, 2026
…o Neither (#34827)

<!-- Please keep the note below for people who find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment whether this change resolves your
issue. Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Root Cause
On Windows, when `ScrollOrientation` was set to `Neither`, the
`ScrollViewer` used `Disabled` scroll modes and scroll bars. Disabling
scrolling caused the control to internally reset its scroll offsets to
the origin `(0,0)`, instead of preserving the current position.
### Description of Change

**Bug fix for ScrollView offset preservation:**

* Updated `ScrollViewerExtensions.cs` so that when
`ScrollOrientation.Neither` is set, the scroll bars are set to `Hidden`
(instead of `Disabled`) and the scroll modes are set to `Disabled`. This
preserves the current scroll position instead of resetting it to (0,0).
When leaving `Neither`, scroll modes are restored to `Auto`.
### Testing :
* Added a new manual test page `Issue34671.cs` that demonstrates and
allows manual verification of the bug and its fix. The page provides
controls to change orientation, scroll to a specific offset, and reset
the state, as well as labels to display current scroll position and
actions.
* Added a new automated UI test `Issue34671.cs` (for Windows and
Android) that verifies the scroll position remains non-zero after
changing orientation to `Neither`, ensuring the fix is validated in CI.

### Note  :
The Test for this fix is already covered in [PR
#34672](#34672), which has been
merged into the inflight branch. The same test has been included here
temporarily so the Gate phase passes. Once PR #34672 is merged into
`main`, the duplicate test in this PR can be reverted, and the
Windows-specific test from PR #34672 can be enabled.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34671 
### Tested the behavior in the following platforms

- [x] Windows
- [ ] Android
- [ ] iOS
- [ ] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/353f4dbc-a009-4035-a907-e52f6a5ca7ff">
| <video
src="https://github.com/user-attachments/assets/ea0891cd-7b7c-433d-9285-64118bf0e0eb">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
PureWeen pushed a commit that referenced this pull request Apr 28, 2026
…o Neither (#34827)

<!-- Please keep the note below for people who find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment whether this change resolves your
issue. Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Root Cause
On Windows, when `ScrollOrientation` was set to `Neither`, the
`ScrollViewer` used `Disabled` scroll modes and scroll bars. Disabling
scrolling caused the control to internally reset its scroll offsets to
the origin `(0,0)`, instead of preserving the current position.
### Description of Change

**Bug fix for ScrollView offset preservation:**

* Updated `ScrollViewerExtensions.cs` so that when
`ScrollOrientation.Neither` is set, the scroll bars are set to `Hidden`
(instead of `Disabled`) and the scroll modes are set to `Disabled`. This
preserves the current scroll position instead of resetting it to (0,0).
When leaving `Neither`, scroll modes are restored to `Auto`.
### Testing :
* Added a new manual test page `Issue34671.cs` that demonstrates and
allows manual verification of the bug and its fix. The page provides
controls to change orientation, scroll to a specific offset, and reset
the state, as well as labels to display current scroll position and
actions.
* Added a new automated UI test `Issue34671.cs` (for Windows and
Android) that verifies the scroll position remains non-zero after
changing orientation to `Neither`, ensuring the fix is validated in CI.

### Note  :
The Test for this fix is already covered in [PR
#34672](#34672), which has been
merged into the inflight branch. The same test has been included here
temporarily so the Gate phase passes. Once PR #34672 is merged into
`main`, the duplicate test in this PR can be reverted, and the
Windows-specific test from PR #34672 can be enabled.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34671 
### Tested the behavior in the following platforms

- [x] Windows
- [ ] Android
- [ ] iOS
- [ ] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/353f4dbc-a009-4035-a907-e52f6a5ca7ff">
| <video
src="https://github.com/user-attachments/assets/ea0891cd-7b7c-433d-9285-64118bf0e0eb">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
PureWeen pushed a commit that referenced this pull request Apr 29, 2026
…o Neither (#34827)

<!-- Please keep the note below for people who find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment whether this change resolves your
issue. Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Root Cause
On Windows, when `ScrollOrientation` was set to `Neither`, the
`ScrollViewer` used `Disabled` scroll modes and scroll bars. Disabling
scrolling caused the control to internally reset its scroll offsets to
the origin `(0,0)`, instead of preserving the current position.
### Description of Change

**Bug fix for ScrollView offset preservation:**

* Updated `ScrollViewerExtensions.cs` so that when
`ScrollOrientation.Neither` is set, the scroll bars are set to `Hidden`
(instead of `Disabled`) and the scroll modes are set to `Disabled`. This
preserves the current scroll position instead of resetting it to (0,0).
When leaving `Neither`, scroll modes are restored to `Auto`.
### Testing :
* Added a new manual test page `Issue34671.cs` that demonstrates and
allows manual verification of the bug and its fix. The page provides
controls to change orientation, scroll to a specific offset, and reset
the state, as well as labels to display current scroll position and
actions.
* Added a new automated UI test `Issue34671.cs` (for Windows and
Android) that verifies the scroll position remains non-zero after
changing orientation to `Neither`, ensuring the fix is validated in CI.

### Note  :
The Test for this fix is already covered in [PR
#34672](#34672), which has been
merged into the inflight branch. The same test has been included here
temporarily so the Gate phase passes. Once PR #34672 is merged into
`main`, the duplicate test in this PR can be reverted, and the
Windows-specific test from PR #34672 can be enabled.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34671 
### Tested the behavior in the following platforms

- [x] Windows
- [ ] Android
- [ ] iOS
- [ ] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/353f4dbc-a009-4035-a907-e52f6a5ca7ff">
| <video
src="https://github.com/user-attachments/assets/ea0891cd-7b7c-433d-9285-64118bf0e0eb">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
github-actions Bot pushed a commit that referenced this pull request May 6, 2026
…o Neither (#34827)

<!-- Please keep the note below for people who find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment whether this change resolves your
issue. Thank you!
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->
### Root Cause
On Windows, when `ScrollOrientation` was set to `Neither`, the
`ScrollViewer` used `Disabled` scroll modes and scroll bars. Disabling
scrolling caused the control to internally reset its scroll offsets to
the origin `(0,0)`, instead of preserving the current position.
### Description of Change

**Bug fix for ScrollView offset preservation:**

* Updated `ScrollViewerExtensions.cs` so that when
`ScrollOrientation.Neither` is set, the scroll bars are set to `Hidden`
(instead of `Disabled`) and the scroll modes are set to `Disabled`. This
preserves the current scroll position instead of resetting it to (0,0).
When leaving `Neither`, scroll modes are restored to `Auto`.
### Testing :
* Added a new manual test page `Issue34671.cs` that demonstrates and
allows manual verification of the bug and its fix. The page provides
controls to change orientation, scroll to a specific offset, and reset
the state, as well as labels to display current scroll position and
actions.
* Added a new automated UI test `Issue34671.cs` (for Windows and
Android) that verifies the scroll position remains non-zero after
changing orientation to `Neither`, ensuring the fix is validated in CI.

### Note  :
The Test for this fix is already covered in [PR
#34672](#34672), which has been
merged into the inflight branch. The same test has been included here
temporarily so the Gate phase passes. Once PR #34672 is merged into
`main`, the duplicate test in this PR can be reverted, and the
Windows-specific test from PR #34672 can be enabled.
<!-- Enter description of the fix in this section -->

### Issues Fixed

<!-- Please make sure that there is a bug logged for the issue being
fixed. The bug should describe the problem and how to reproduce it. -->

Fixes #34671 
### Tested the behavior in the following platforms

- [x] Windows
- [ ] Android
- [ ] iOS
- [ ] Mac

| Before Issue Fix | After Issue Fix |
|----------|----------|
| <video
src="https://github.com/user-attachments/assets/353f4dbc-a009-4035-a907-e52f6a5ca7ff">
| <video
src="https://github.com/user-attachments/assets/ea0891cd-7b7c-433d-9285-64118bf0e0eb">
|
<!--
Are you targeting main? All PRs should target the main branch unless
otherwise noted.
-->
TamilarasanSF4853 added a commit to TamilarasanSF4853/maui that referenced this pull request May 13, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators May 18, 2026
@kubaflo kubaflo added s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) labels May 20, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-scrollview ScrollView community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/windows s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] ScrollView offsets do not preserve when Orientation changes to Neither

7 participants